home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
answrbok
/
6_6.lha
/
6_6
/
6_6.h
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
5KB
|
327 lines
* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */
* The C++ Answer Book */
* Tony Hansen */
* All rights reserved. */
/ Exercise 6.6
/ String class with value semantics,
/ delayed copying on assignment, and
/ substring and contenation operators.
ifndef STR_H
define STR_H
include <stream.h>
include <string.h>
/ define the class to manage the
/ actual character string
lass srep
char *s;
int size;
int refcnt;
friend class string;
friend class substring;
srep()
{
refcnt = 1;
s = new char[size = 1];
s[0] = 0;
}
srep(int sz)
{
refcnt = 1;
s = new char[size = sz];
s[0] = 0;
}
srep(char *x)
{
refcnt = 1;
s = new char[size = strlen(x) + 1];
strcpy(s, x);
}
srep(char *x, int len)
{
refcnt = 1;
s = new char[size = len + 1];
strncpy(s, x, len);
}
srep& operator=(srep &x)
{
delete s;
refcnt = 1;
s = new char[size = x.size];
strcpy(s, x.s);
return *this;
}
srep& operator=(char *x)
{
delete s;
refcnt = 1;
s = new char[size = strlen(x) + 1];
strcpy(s, x);
return *this;
}
// Reallocate the char space, copying
// in the specified string. Delay deleting
// the old string in case the string to
// copy is from there.
void realloc(char *ns, int nlen)
{
char *olds = s;
s = new char[size = nlen];
strcpy(s, ns);
delete olds;
}
~srep()
{ delete s; }
;
/ a helper typedef for the cast
/ back into a character pointer
ypedef const char *charptr;
lass string
srep *p;
friend class string_iterator;
friend class substring;
char *str()
{ return p->s; }
int len()
{ return p->size; }
int refcnt() // DELETE
{ return p->refcnt; } // DELETE
ublic:
// string s;
string()
{ p = new srep; }
// string s(5);
string(int sz)
{ p = new srep(sz); }
// string s("xyz");
string(char *s)
{ p = new srep(s); }
// string s(string)
string(string &s)
{ s.p->refcnt++; p = s.p; }
// string(substring)
string(substring&);
~string()
{
if (--p->refcnt == 0)
delete p;
}
// s = string
string& operator=(string &s)
{
s.p->refcnt++;
if (--p->refcnt == 0)
delete p;
p = s.p;
return *this;
}
// s = "xyz";
string& operator=(char *s)
{
if (p->refcnt > 1)
{
p->refcnt--;
p = new srep(s);
}
else
p->realloc(s, strlen(s) + 1);
return *this;
}
// s = substring;
string& operator=(substring&);
// const char *c = s;
charptr operator charptr()
{
return (charptr) str();
}
// substring x = s(3,5);
substring operator()(int i, int len = -1);
// x = s[3];
// s[3] = 'x';
char &operator[](int i)
{
if (i < 0 || i >= len())
return str()[0];
else
return str()[i];
}
// concatenation
// str = str1 + str2;
friend string operator+(string &s1, string &s2)
{
string ret(s1.len() + s2.len() - 1);
strcpy(ret.str(), s1.str());
strcat(ret.str(), s2.str());
return ret;
}
// append to end
// str1 += str2;
string &operator+=(string &s)
{
int nlen = len() + s.len();
// have to disconnect from
// the old string
if (p->refcnt > 1)
{
p->refcnt--;
srep *oldp = p;
p = new srep(oldp->s, nlen);
strcat(str(), s.str());
}
// we can reallocate the
// current string area
else
{
p->realloc(p->s, nlen);
strcat(str(), s.str());
}
return *this;
}
friend ostream& operator<<(ostream&, string&);
friend istream& operator>>(istream&, string&);
define defop(op) \
friend int operator op(string &x, char *s) \
{ return strcmp(x.str(), s) op 0; } \
friend int operator op(string &x, string &y) \
{ return strcmp(x.str(), y.str()) op 0; }
defop(==); defop(!=);
defop(<); defop(<=);
defop(>); defop(>=);
undef defop
;
lass string_iterator
char *cp;
ublic:
string_iterator(string &s)
{ cp = s.str(); }
char& operator()()
{ char *r = cp++; return *r; }
;
lass substring
friend class string;
char *s; // ptr to substring start
int len; // length of substring
string *str; // ptr to parent string
substring(char *chptr, int stlen, string *stptr)
{
s = chptr;
len = stlen;
str = stptr;
}
ublic:
// substring x = ...
substring(substring &sst)
{
s = sst.s;
len = sst.len;
str = sst.str;
}
substring &operator=(substring&);
substring &operator=(string&);
substring &operator=(char*);
// cout << substring
friend ostream &operator<<(ostream&, substring&);
;
/ cout << string
nline ostream &operator<<(ostream &s, string &x)
ifdef NOTDEF // DELETE
return s << x.str();
else // DELETE
return s << x.str() << // DELETE
"[len=" << x.len() << ",ref=" << x.refcnt() << "]"; // DELETE
endif // DELETE
/ cout << substring
nline ostream &operator<<(ostream &out, substring &sst)
string st(sst);
return out << st;
/ cin >> string
nline istream& operator>>(istream &s, string &x)
char buf[1024];
s >> buf;
x = buf;
return s;
/ s = substring;
nline string& string::operator=(substring &sst)
string st(sst);
return *this = st;
/ string(substring)
tring::string(substring &sst)
p = new srep(sst.s, sst.len);
/ substring = string
nline substring &substring::operator=(string &st)
return *this = st.str();
/ substring = substring
nline substring &substring::operator=(substring &sst)
string st(sst);
return *this = st;
endif /* STR_H */